﻿namespace JobsTest
{
    using FluentScheduler;
    using System;
    using static Serilog.Log;
    using static System.Threading.Thread;

    /// <summary>
    /// 自定义的Job注册类
    /// </summary>
    public class MyRegistry : Registry
    {
        /// <summary>
        /// 注册各类任务
        /// </summary>
        public MyRegistry()
        {
            //启用一次的任务
            Welcome();

            //不可并发的任务
            NonReentrant();
            //可并发的任务
            Reentrant();
            //移除Jobs
            Disable();

            //任务执行发生异常
            Faulty();
            //任务被删除
            Removed();
            //接收参数的任务
            Parameter();
            //自动销毁的任务
            Disposable();

            //500毫秒周期任务
            FiveHundredMilliseconds();
            //5分钟周期任务
            FiveMinutes();
            //10分钟周期任务
            TenMinutes();
            //小时周期任务
            Hour();
            //天周期任务
            Day();
            //周任务
            Weekday();
            //周任务
            Week();
        }

        /// <summary>
        /// 启动一次的任务
        /// </summary>
        private void Welcome()
        {
            //计划任务
            Schedule(() => Logger.Information("CountDown: 3"))
                //任务名称
                .WithName("Countdown")
                //继续执行一个任务
                .AndThen(() => Logger.Information("Countdown: 2"))
                //继续执行一个任务
                .AndThen(() => Logger.Information("Countdown: 1"))
                //继续执行一个任务
                .AndThen(() => Logger.Information("Countdown: live!"));
        }

        private void NonReentrant()
        {
            Schedule(() =>
            {
                Logger.Information("NonReentrant: sleeping a minute");
                Sleep(TimeSpan.FromMinutes(1));
            })
                //任务不可并发，上一次没有执行完成，下一次不会执行
                .NonReentrant()
                //任务名称
                .WithName("NonReentrant")
                //任务循环执行
                .ToRunEvery(1)
                //时间为秒
                .Seconds();
        }

        private void Reentrant()
        {
            Schedule(() =>
            {
                Logger.Information("Reentrant: sleeping a minute");
                Sleep(TimeSpan.FromMinutes(3));
            }).WithName("Reentrant")
            //任务立即执行
            .ToRunNow()
            //然后等待1分钟后开始
            .AndEvery(1)
            //时间为分钟
            .Minutes();
        }

        private void Disable()
        {
            Schedule(() =>
            {
                //移除任务
                JobManager.RemoveJob("Reentrant");
                JobManager.RemoveJob("NonReentrant");

                Logger.Information("Disable: disabled Reentrant and NonReentrant jobs");
            }).WithName("Disable")
            //在指定时间后，任务执行一次
            .ToRunOnceIn(200)
            //时间为秒
            .Seconds();
        }

        private void Faulty()
        {
            Schedule(() =>
            {
                Logger.Information("Faulty: throwing an exception");
                //抛出异常
                throw new Exception("Exception from Faulty job");
            }).WithName("Faulty")
            .ToRunNow().AndEvery(1).Minutes();
        }

        private void Removed()
        {
            //这个任务在其它地方被移除了
            Schedule(() =>
            {
                Logger.Information("SOMETHING WENT WRONG");
            }).WithName("Removed").ToRunOnceIn(2).Minutes();
        }

        private void Parameter()
        {
            //向任务传递参数
            //任务为具体的类ParameterJob,继承自IJob
            //通过属性传递参数
            Schedule(new ParameterJob { Parameter = "Foo" }).WithName("Parameter").ToRunOnceIn(10).Seconds();
        }

        private void Disposable()
        {
            //任务内容为DisposableJob，这个Job实现了IJob和IDisposable
            //任务结束后会自动调用IDisposable销毁对象
            Schedule<DisposableJob>().WithName("Disposable").ToRunOnceIn(10).Seconds();
        }

        private void FiveHundredMilliseconds()
        {
            //500毫秒周期
            Schedule(() => Logger.Information("HalfSecond: half a second has passed"))
                .WithName("HalfSecond").ToRunOnceIn(500).Milliseconds();
        }

        private void FiveMinutes()
        {
            //5分钟周期
            Schedule(() => Logger.Information("FiveMinutes: five minutes has passed"))
                .WithName("FiveMinutes").ToRunOnceAt(DateTime.Now.AddMinutes(5)).AndEvery(5).Minutes();
        }

        private void TenMinutes()
        {
            //10分钟周期
            Schedule(() => Logger.Information("TenMinutes: ten minutes has passed"))
                .WithName("TenMinutes").ToRunEvery(10).Minutes();
        }

        private void Hour()
        {
            //n小时周期
            Schedule(() => Logger.Information("Hour: a hour has passed"))
                .WithName("Hour").ToRunEvery(1).Hours();
        }

        private void Day()
        {
            //n天周期
            Schedule(() => Logger.Information("Day: a day has passed"))
                .WithName("Day").ToRunEvery(1).Days();
        }

        private void Weekday()
        {
            //n天周期，周六周日忽略
            Schedule(() => Logger.Information("Weekday: a new weekday has started"))
                .WithName("Weekday").ToRunEvery(1).Weekdays();
        }

        private void Week()
        {
            //n星期周期
            Schedule(() => Logger.Information("Week: a new week has started"))
                .WithName("Week").ToRunEvery(1).Weeks();
        }
    }
}
